<template>
  <div class="s-pagination">
    <button
      type="button"
      class="btn-prev number"
      :disabled="myCurrentPage === 1"
      @click="prev"
    >
      <i class="iconfont icon-arrow-left-bold"></i>
    </button>

    <ul class="s-pager">
      <li
        :class="{
          number: true,
          active: myCurrentPage === 1,
        }"
        @click="myCurrentPage = 1"
      >
        1
      </li>
      <li class="number iconfont icon-elipsis" v-if="startEnd.start > 2"></li>

      <!-- 遍历的number数据不能是负数，否则会报错 -->
      <!-- 
        遍历的数量：
          1 ... 3 4 [5] 6 7 ... 34
          1 2 [3] 4 
          找规律: startEnd.end - startEnd.start + 1
        
        key的值问题：保证唯一，更新前后保证key一致
          3 4 [5] 6 7

          4 5 [6] 7 8
       -->
      <li
        v-for="(item, index) in startEnd.end - startEnd.start + 1"
        :key="startEnd.start + index"
        :class="{
          number: true,
          active: myCurrentPage === startEnd.start + index,
        }"
        @click="myCurrentPage = startEnd.start + index"
      >
        {{ startEnd.start + index }}
      </li>

      <li
        class="number iconfont icon-elipsis"
        v-if="startEnd.end < totalPages - 1"
      ></li>
      <li
        :class="{
          number: true,
          active: myCurrentPage === totalPages,
        }"
        @click="myCurrentPage = totalPages"
        v-if="totalPages > 1"
      >
        {{ totalPages }}
      </li>
    </ul>

    <button
      type="button"
      class="btn-next number"
      :disabled="myCurrentPage >= totalPages"
      @click="next"
    >
      <i class="iconfont icon-arrow-right-bold"></i>
    </button>

    <select class="s-pagination__sizes" v-model="myPageSize">
      <option v-for="pageSize in pageSizes" :key="pageSize" :value="pageSize">
        {{ pageSize }} 条/页
      </option>
    </select>

    <span class="s-pagination__total">共 {{ total }} 条</span>
  </div>
</template>

<script>
export default {
  name: "SPagination",
  // props数据是只读的，不能直接修改
  props: {
    // 外面传递prop属性其实是 current-page
    // 内部可以通过小驼峰声明接受 currentPage
    currentPage: {
      type: Number,
      default: 1,
    },
    pageSize: {
      type: Number,
      default: 5,
    },
    pageSizes: {
      type: Array,
      default: () => [5, 10, 15, 20],
    },
    total: {
      type: Number,
      default: 0,
    },
  },
  computed: {
    // 总页数
    totalPages() {
      return Math.ceil(this.total / this.myPageSize);
    },
    // 中间按钮（排除开头1，结尾总页面）
    startEnd() {
      /*
        场景1：
          1 ... 3 4 [5] 6 7 ... 34

          计算结果：
            start = 5 - 2 = 3
            end = 3 + 4 = 7

        场景2：
          1 [2] 3 4 5 6 ... 34
          [1] 2 3 4 5 6 ... 34

          计算结果：
            start = 2 - 2 = 0 < 2 = 2
            end = 2 + 4 = 6

        场景3：
          1 ... 29 30 31 32 [33] 34

          计算结果：
            start = 33 - 2 = 31
            end = 31 + 4 = 35 > 33 = 33

        场景4:
          1 2 [3] 4 
          1 2 [3] 4 5
          1 2 [3] 4 5 6
          1 2 [3] 4 5 6 7

        场景5：
          1 [2]
          [1]

          不要中间按钮。最终遍历的值为0

          但总页数为0或1时，计算结果是负数，会报错
          end - start + 1 = 0
      */
      const { myCurrentPage, totalPages } = this;

      if (totalPages <= 1) {
        return {
          start: 2,
          end: 1,
        };
      }

      // 解决：场景4问题
      if (totalPages <= 7) {
        return {
          start: 2,
          end: totalPages - 1,
        };
      }

      // 中间按钮开头
      let start = myCurrentPage - 2;

      // start有最小值：2
      if (start < 2) start = 2;

      // const end = currentPage + 2;
      // 中间按钮的结尾
      let end = start + 4;

      // end有最大值
      if (end > totalPages - 1) {
        // 一旦end计算错误，start也会计算错误
        // 修改end的值
        end = totalPages - 1;
        // 修改start的值
        start = end - 4;
      }

      return {
        start,
        end,
      };
    },
  },
  data() {
    return {
      myCurrentPage: this.currentPage,
      myPageSize: this.pageSize,
    };
  },
  methods: {
    prev() {
      this.myCurrentPage--;
    },
    next() {
      this.myCurrentPage++;
    },
  },
  watch: {
    myCurrentPage(currentPage) {
      this.$emit("current-change", currentPage);
    },
    myPageSize(pageSize) {
      // 每页条数发生变化，可能会导致当前页码超过了totalPages
      if (this.myCurrentPage > this.totalPages) {
        this.myCurrentPage = this.totalPages;
      }
      this.$emit("size-change", pageSize);
    },
  },
};
</script>

<style lang="less" scoped>
.s-pagination {
  display: flex;
  align-items: center;
  white-space: nowrap;
  padding: 2px 5px;
  color: #303133;
  font-weight: 700;
}

.s-pager {
  display: flex;
}

.number {
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
  text-align: center;
  height: 28px;
  line-height: 28px;
  cursor: pointer;
  &:hover:not(.active, .btn-next, .btn-prev) {
    color: #e1251b;
  }
}
.active {
  background-color: #e1251b;
  color: #fff;
}

.btn-prev,
.btn-next {
  cursor: pointer;
  margin: 0;
  outline: none;
  border: none;
  &:disabled {
    color: #c0c4cc;
    cursor: not-allowed;
  }
}

.s-pagination__sizes {
  outline: none;
  margin: 0 20px;
  height: 28px;
}

.s-pagination__total {
  font-weight: 400;
  color: #606266;
  font-size: 13px;
}
</style>
